/***********************************************************************
 * Fulguro Example 4 : Beans count
 ***********************************************************************/
#include <flgrCoreTypes.h>
#include <flgrCoreErrors.h>
#include <flgrCoreData.h>
#include <flgrCoreIO.h>
#include <flgrCoreCompare.h>
#include <flgrCoreReplace.h>
#include <flgrImageIO.h>
#include <flgrMeasureBase.h>
#include <flgrMorphoBase.h>
#include <flgrMorphoWatershed.h>
#include <flgrMorphoGeodesy.h>
#include <flgrMorphoLabel.h>
#include <flgrMorphoDistance.h>
#include <time.h>

#define BENCH_FUCTION(nbtime,textinfo,function,...)			\
  {									\
    clock_t before, after;						\
    int i;								\
    before=clock();							\
    for(i=0;i<nbtime;i++) {						\
      function(__VA_ARGS__);						\
    }									\
    after=clock();							\
    printf(textinfo " time : %d us \n",					\
	   (int) ((after - before)/(CLOCKS_PER_SEC/1000000)/nbtime));	\
  }


int main(void) {
  FLGR_Data2D *imin,*imtmp,*imFilter,*imDistance,*imMarker,*imMaxima,*imLabel,*imWatershed;
  FLGR_Data2D *nhb1,*nhb2,*nhb3,*nhb4,*nhb5;
  
  FLGR_Vector *vec_min, *vec_max;
  FLGR_Vector *vec_hmin;

  imin        = flgr2d_load_pgm("../../images/gray/beans.pgm");
  imtmp       = flgr2d_create_from(imin);
  imFilter    = flgr2d_create_from(imin);
  imDistance  = flgr2d_create_from(imin);
  imMarker    = flgr2d_create_from(imin);
  imMaxima    = flgr2d_create_from(imin);
  imLabel     = flgr2d_create_from(imin);
  imWatershed = flgr2d_create_from(imin);
  
  vec_min  = flgr_vector_create(imin->spp,imin->type);
  vec_max  = flgr_vector_create(imin->spp,imin->type);
  vec_hmin = flgr_vector_create(imin->spp,imin->type);
  flgr_vector_populate_from_string(vec_hmin,"1");


  nhb1 = flgr2d_create_neighborhood(3,3,imin->spp,imin->type,FLGR_RECT,FLGR_8_CONNEX);
  nhb2 = flgr2d_create_neighborhood(5,5,imin->spp,imin->type,FLGR_RECT,FLGR_8_CONNEX);
  nhb3 = flgr2d_create_neighborhood(7,7,imin->spp,imin->type,FLGR_RECT,FLGR_8_CONNEX);
  nhb4 = flgr2d_create_neighborhood(9,9,imin->spp,imin->type,FLGR_RECT,FLGR_8_CONNEX);
  nhb5 = flgr2d_create_neighborhood(11,11,imin->spp,imin->type,FLGR_RECT,FLGR_8_CONNEX);

  flgr2d_replace_I_with_S_S_I(imin,imin,"==","255","254",imin);

  //Filter
  BENCH_FUCTION(1000,"Open Filter",flgr2d_open,imtmp,imin,nhb1);
  flgr2d_close(imFilter,imtmp,nhb1);

  // Distance
  flgr2d_replace_I_with_S_S_S(imtmp,imFilter,"<","128","255","0");
  flgr2d_distance(imDistance,imtmp,nhb1->connexity);

  // Distance Maxima
  flgr2d_regional_hmaxima(imMaxima,imDistance,vec_hmin,nhb1->connexity);
  flgr2d_replace_I_with_S_S_S(imtmp,imMaxima,">","0","255","0");
  flgr2d_dilate(imMaxima,imtmp,nhb5);

  // Labelize Maxima
  flgr2d_label(imLabel, imMaxima, nhb1->connexity);

  // Watershed
  BENCH_FUCTION(1,"Watershed",flgr2d_watershed,imLabel, imin, nhb1->connexity);


  flgr2d_watershed_build_line(imWatershed, imLabel, nhb1->connexity);
  flgr2d_replace_I_with_S_S_I(imWatershed,imWatershed,"==","1","255",imin);

  flgr2d_measure_min_max(imLabel,vec_min,vec_max);

  printf("Coffee Beans number : %d\n", flgr_get_array_fgUINT8(vec_max->array,0));
 
  flgr2d_save_pgm(imFilter,"filter.pgm",5);
  flgr2d_save_pgm(imDistance,"distance.pgm",5);
  flgr2d_save_pgm(imMaxima,"maxima.pgm",5);
  flgr2d_save_pgm(imLabel,"label.pgm",5);
  flgr2d_save_pgm(imWatershed,"watershed.pgm",5);

  flgr2d_destroy(imin);
  flgr2d_destroy(imtmp);
  flgr2d_destroy(imFilter);
  flgr2d_destroy(imDistance);
  flgr2d_destroy(imMarker);
  flgr2d_destroy(imMaxima);
  flgr2d_destroy(imLabel);
  flgr2d_destroy(imWatershed);
  flgr2d_destroy(nhb1);
  flgr2d_destroy(nhb2);
  flgr2d_destroy(nhb3);
  flgr2d_destroy(nhb4);
  flgr2d_destroy(nhb5);

  flgr_vector_destroy(vec_max);
  flgr_vector_destroy(vec_min);
  flgr_vector_destroy(vec_hmin);
 
  return 0;
}


/*! 
 * \example example4.c <B>Automatic Coffee Beans Counting</B>
 * \image html example4_beans.png "Original Beans Image"
 * \image html example4_filter.png "Alternate Filter Size 3x3"
 * \image html example4_distance.png "Distance Function"
 * \image html example4_marker.png "Marker for watershed segmentation"
 * \image html example4_label.png "Labelized image thanks to watershed alogirthm"
 * \image html example4_wshedline.png "Watershed line"
 * \image latex example4_beans.png "Original Beans Image" width=5cm
 * \image latex example4_filter.png "Alternate Filter Size 3x3" width=5cm
 * \image latex example4_distance.png "Distance Function" width=5cm
 * \image latex example4_marker.png "Marker for watershed segmentation" width=5cm
 * \image latex example4_label.png "Labelized image thanks to watershed alogirthm" width=5cm
 * \image latex example4_wshedline.png "Watershed line" width=5cm
 */
